package cn.liutao.order.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.liutao.common.enums.CommonEnum;
import cn.liutao.common.enums.OrderEnum;
import cn.liutao.common.exception.OrderException;
import cn.liutao.common.utils.ServletUtils;
import cn.liutao.dish.entity.po.Dish;
import cn.liutao.dish.entity.po.Taste;
import cn.liutao.dish.mapper.DishMapper;
import cn.liutao.dish.mapper.TasteMapper;
import cn.liutao.order.entity.po.Cart;
import cn.liutao.order.entity.vo.CartVo;
import cn.liutao.order.mapper.CartMapper;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.relation.RelationManager;

import java.math.BigDecimal;
import java.util.List;

import static cn.liutao.order.entity.po.table.CartTableDef.CART;

/**
 * 购物车表 服务层实现。
 *
 * @author liutao
 * @since 2023-11-01
 */

public class CartService {
    private static volatile CartService instance;
    private CartMapper cartMapper;
    private DishMapper dishMapper;
    private TasteMapper tasteMapper;

    private CartService() {
        cartMapper = ServletUtils.getMapper(CartMapper.class);
        dishMapper = ServletUtils.getMapper(DishMapper.class);
        tasteMapper = ServletUtils.getMapper(TasteMapper.class);
    }

    public static CartService getInstance() {
        if (instance == null) {
            synchronized (CartService.class) {
                if (instance == null) {
                    instance = new CartService();
                }
            }
        }
        return instance;
    }


    public Page<CartVo> selectByList(Cart queryParam) {
        QueryWrapper qw = QueryWrapper.create()
                .where(CART.STATUS.eq(queryParam.getStatus()))
                .and(CART.TYPE.eq(queryParam.getStatus()))
                .and(CART.TASTE_ID.eq(queryParam.getTasteId()))
                .and(CART.DISH_ID.eq(queryParam.getDishId()))
                .and(CART.PRICE.eq(queryParam.getDishId()))
                .and(CART.USER_ID.eq(queryParam.getUserId()));
        RelationManager.addExtraConditionParam("dishStatus", CommonEnum.STATUS_ON.getIntValue());
        RelationManager.addExtraConditionParam("tasteStatus", CommonEnum.STATUS_ON.getIntValue());
        Page<CartVo> page = cartMapper.paginateWithRelationsAs(queryParam.getPageNum(), queryParam.getPageSize(), qw, CartVo.class);
        //设置单价
        genUnitPrice(page.getRecords());
        return page;
    }

    public void insert(Cart addParam) {
        //查询单价
        BigDecimal singlePrice = getPrice(addParam);
        //判断菜品以及此口味是否存在
        QueryWrapper qw = QueryWrapper.create()
                .where(CART.DISH_ID.eq(addParam.getDishId()))
                .and(CART.USER_ID.eq(addParam.getUserId()))
                .and(CART.TYPE.eq(OrderEnum.CART_TYPE_ADD_CART.getIntValue()))
                .and(CART.STATUS.eq(OrderEnum.CART_STATUS_NO_BUY.getIntValue()))
                .and(CART.TASTE_ID.eq(addParam.getTasteId()));
        Cart cart = cartMapper.selectOneByQuery(qw);
        if (ObjectUtil.isNotNull(cart)) {
            //修改操作
            int total = addParam.getQuantity() + cart.getQuantity();
            BigDecimal totalNum = new BigDecimal(total);
            BigDecimal totalPrice = singlePrice.multiply(totalNum);
            cart.setQuantity(totalNum.intValue());
            cart.setPrice(totalPrice);
            cartMapper.update(cart);
            return;
        }
        //新增
        BigDecimal totalPrice = singlePrice.multiply(new BigDecimal(addParam.getQuantity()));
        addParam.setPrice(totalPrice);
        cartMapper.insert(addParam);
    }

    public void updateById(Cart editParam) {
        boolean flag = checkCart(editParam);
        if (!flag){
            return;
        }
        if (editParam==null){
            throw new OrderException("购物车不存在");
        }
        //查询单价
        BigDecimal singlePrice = getPrice(editParam);
        //当前数量为0删除
        if (editParam.getQuantity() == 0) {
            cartMapper.delete(editParam);
        } else {
            //当前数量不为0修改
            BigDecimal totalPrice = singlePrice.multiply(new BigDecimal(editParam.getQuantity()));
            editParam.setPrice(totalPrice);
            cartMapper.update(editParam);
        }
    }

    /**
     * 用于查询规格单价
     * @param cart 购物车对象
     * @return 返回单价
     */
    public BigDecimal getPrice(Cart cart) {
        Dish dish = dishMapper.selectOneById(cart.getDishId());
        if (ObjectUtil.isNull(dish)){
            return BigDecimal.ZERO;
        }
        Taste taste = tasteMapper.selectOneById(cart.getTasteId());
        BigDecimal singlePrice = BigDecimal.ZERO;
        if (taste==null) {
            singlePrice = singlePrice.add(dish.getPrice());
        } else {
            singlePrice = dish.getPrice().add(taste.getPrice());
        }
        return singlePrice;
    }

    public void removeById(Integer id) {
        cartMapper.deleteById(id);
    }


    /**
     * 设置单价
     * @param cartVo 购物车vo对象列表
     * @return 返回单价
     */
    public BigDecimal genUnitPrice(CartVo cartVo) {
        BigDecimal unitPrice = BigDecimal.ZERO;
        Dish dish = cartVo.getDish();
        Taste taste = cartVo.getTaste();
        if (dish !=null) unitPrice = unitPrice.add(dish.getPrice()==null?BigDecimal.ZERO:dish.getPrice());
        if (taste !=null) unitPrice = unitPrice.add(taste.getPrice()==null?BigDecimal.ZERO:taste.getPrice());
        cartVo.setUnitPrice(unitPrice);
        return unitPrice;
    }

    /**
     * 设置单价
     * @param cartVoList 购物车vo对象列表
     */
    public void genUnitPrice(List<CartVo> cartVoList) {
        cartVoList.forEach(cartVo -> {
            genUnitPrice(cartVo);
        });
    }

    private boolean checkCart(Cart checkCart){
        Integer cartId = checkCart.getId();
        Cart cart = cartMapper.selectOneById(cartId);
        if (cart==null){
            return false;
        }
        Dish dish = dishMapper.selectOneById(cart.getDishId());
        if (dish==null){
            cartMapper.deleteById(cartId);
            return false;
        }
        BeanUtil.copyProperties(cart,checkCart,"quantity");
        return true;
    }
}
